package org.jeecg.modules.basic.demo.apartment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.IdGeneratorSnowflake;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.basic.demo.apartment.entity.LwgyApartmentCustom;
import org.jeecg.modules.basic.demo.apartment.entity.LwgyBaseApartment;
import org.jeecg.modules.basic.demo.apartment.entity.LwgyBaseApartmentTreeList;
import org.jeecg.modules.basic.demo.apartment.mapper.LwgyBaseApartmentMapper;
import org.jeecg.modules.basic.demo.apartment.service.ILwgyBaseApartmentService;
import org.jeecg.modules.basic.demo.apartment.utils.FindsApartmentChildrenUtil;
import org.jeecg.modules.basic.demo.bed.entity.LwgyBaseBed;
import org.jeecg.modules.basic.demo.bed.entity.LwgyBedAssignment;
import org.jeecg.modules.basic.demo.bed.mapper.LwgyBaseBedMapper;
import org.jeecg.modules.basic.demo.bed.service.ILwgyBaseBedService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Description: 学校公寓信息
 * @Author: CSD
 * @Date: 2020-12-28
 * @Version: V1.9
 */
@Service
public class LwgyBaseApartmentServiceImpl extends ServiceImpl<LwgyBaseApartmentMapper, LwgyBaseApartment> implements ILwgyBaseApartmentService {

    @Autowired
    private ILwgyBaseBedService lwgyBaseBedService;

    @Resource
    private LwgyBaseApartmentMapper lwgyBaseApartmentMapper;

    @Resource
    private LwgyBaseBedMapper lwgyBaseBedMapper;

    @Autowired
    private IdGeneratorSnowflake snowflake;
    //code必填版本-csd
    @Override
    public void addLwgyBaseApartment(LwgyBaseApartment lwgyBaseApartment) {
        String pid = lwgyBaseApartment.getPid();
        String maxInnerCode = get_maxInnerCode(pid);
        if (maxInnerCode != null && !oConvertUtils.isEmpty(lwgyBaseApartment.getPid())) {
            lwgyBaseApartment.setInnerCode(getInnerCodeByList2(maxInnerCode));
            lwgyBaseApartment.setRoomCoordinates(lwgyBaseApartment.getName());
        }
        if (oConvertUtils.isEmpty(lwgyBaseApartment.getPid()) && maxInnerCode == null) {//如果是顶级节点，并且inner_code 是 null
            lwgyBaseApartment.setInnerCode("001");//创建inner_code为001

        }
        if (oConvertUtils.isEmpty(lwgyBaseApartment.getPid()) && maxInnerCode != null) {//如果是顶级节点，并且inner_code 不是 null
            String suffix = maxInnerCode.substring(0, maxInnerCode.length() - 3);
            String prefix = maxInnerCode.substring(maxInnerCode.length() - 3);
            int innerCode = Integer.parseInt(prefix) + 1;
            String s = String.format("%0" + 3 + "d", innerCode);
            s = suffix + s;
            lwgyBaseApartment.setInnerCode(s);
            lwgyBaseApartment.setRoomCoordinates(lwgyBaseApartment.getName());
        }
        if (!oConvertUtils.isEmpty(lwgyBaseApartment.getPid()) && maxInnerCode == null) {//如果不是是顶级节点，并且inner_code 是 null
            String innerCode = get_parentInnerCode(pid);//先获取父节点的inner_code
            lwgyBaseApartment.setInnerCode(getInnerCodeByList2(innerCode + "0000"));
            lwgyBaseApartment.setRoomCoordinates(lwgyBaseApartment.getName());
        }
        if (oConvertUtils.isEmpty(lwgyBaseApartment.getPid())) {
            lwgyBaseApartment.setPid(ILwgyBaseApartmentService.ROOT_PID_VALUE);
        } else {
            //如果当前节点父ID不为空 则设置父节点的hasChildren 为1
            LwgyBaseApartment parent = baseMapper.selectById(lwgyBaseApartment.getPid());
            if (parent != null && !"1".equals(parent.getHasChild())) {
                parent.setHasChild("1");
                baseMapper.updateById(parent);
                lwgyBaseApartment.setRoomCoordinates(lwgyBaseApartment.getName());
            }
        }
        baseMapper.insert(lwgyBaseApartment);
    }

    //code自动生成版本
    /*public void addLwgyBaseApartment(LwgyBaseApartment lwgyBaseApartment) {
        //上级节点,为空是顶级菜单
        String pid = lwgyBaseApartment.getPid();
        //类型：包括，校区，楼宇，单元，楼层，房间什么的
        String type = lwgyBaseApartment.getType();
        String code="";
        String innercode="";
        String new_code="";
        String new_innercode="";

        //如果是顶级菜单，并且要添加校区
        if(oConvertUtils.isEmpty(pid)){
            lwgyBaseApartment.setPid(ILwgyBaseApartmentService.ROOT_PID_VALUE);

            //查询同一级的最大值，为空默认1，非空+1
            List<LwgyBaseApartment> list = getSameLeveList("0");
            System.out.println("list;"+list);
            if(oConvertUtils.isNotEmpty(list) && list.size()>0){
                //取code innercode 最大值+1
                String value[] = getCodeByList(list);
                new_code=String.valueOf(Integer.parseInt(value[0]) + 1);
                new_innercode="00"+String.valueOf(Integer.parseInt(value[1]) + 1);
                System.out.println("new_code:"+new_code +"----------new_innerCode"+new_innercode);
            }else{
                //code inner 为1
                new_code="1";
                new_innercode="001";
            }

        }else{
            //不是顶级菜单
            //查询同一级的最大值，为空默认上一级数据追加1（id=pid），非空+1

            List<LwgyBaseApartment> list = getSameLeveList(pid);
            if(oConvertUtils.isNotEmpty(list) && list.size()>0){
                //存在同一级，获取最大值+1
                String value[] = getCodeByList(list);
                code=value[0];
                innercode=value[1];
                int endInt = Integer.parseInt(code.substring(code.lastIndexOf("-") + 1))+1;
                new_code=code.substring(0,code.lastIndexOf("-") )+"-"+endInt;
                String suffix = innercode.substring(0, innercode.length() - 3);
                String prefix = innercode.substring(innercode.length() - 3);
                int innerCode = Integer.parseInt(prefix) + 1;
                if(innerCode>10){
                    new_innercode = suffix +String.format("%0" + 2 + "d", innerCode);
                }else{
                    new_innercode = suffix +String.format("%0" + 3 + "d", innerCode);
                }

                System.out.println("new_innercode:"+new_innercode);
            }else{
                //不存在同一级，取上一级的最大值
                List<LwgyBaseApartment> list2 = getUpOneLeveList(pid);
                //上一级存在数据，往后追加1，上一级不存在，数据有问题。
                if(oConvertUtils.isNotEmpty(list2) && list2.size()>0){
                    String value[] = getCodeByList(list2);
                    code=value[0];
                    innercode=value[1];
                    new_code=code+"-1";
                    new_innercode=innercode+"001";
                }

            }
            //如果当前节点父ID不为空 则设置父节点的hasChildren 为1
            LwgyBaseApartment parent = baseMapper.selectById(pid);
            if (parent != null && !"1".equals(parent.getHasChild())) {
                parent.setHasChild("1");
                baseMapper.updateById(parent);
            }
        }

        lwgyBaseApartment.setRoomCoordinates(lwgyBaseApartment.getName());
        lwgyBaseApartment.setCode(new_code);
        lwgyBaseApartment.setInnerCode(new_innercode);
        lwgyBaseApartment.setHasChild("0");

        //      String[] codeArray = (String[]) FillRuleUtil.executeRuleSchool(FillRuleConstant.DEPART, formData);
        //update-end--Author:baihailong  Date:20191209 for：部门编码规则生成器做成公用配置
       // lwgyBaseSchool.setSysOrgCode(codeArray[0]);
      //  lwgyBaseSchool.setDelFlag("0")

        if("room".equals(type)){//如果是房间节点，有些字段必填，如果没有影响展示
            if(oConvertUtils.isEmpty(lwgyBaseApartment.getRoomType())){ //房间类型 默认功能房
                lwgyBaseApartment.setRoomType("hotel_room");
            }
            if(oConvertUtils.isEmpty(lwgyBaseApartment.getRoomOrientation())){ //房间朝向 默认南
                lwgyBaseApartment.setRoomOrientation("south");
            }
            if(oConvertUtils.isEmpty(lwgyBaseApartment.getRoomSex())){  //房间性别 默认女
                lwgyBaseApartment.setRoomSex("2");
            }

        }
        baseMapper.insert(lwgyBaseApartment);
    }*/
    //获取同一级的list列表
    public List<LwgyBaseApartment> getSameLeveList(String pid){
        QueryWrapper<LwgyBaseApartment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("pid", pid);//同级菜单
        queryWrapper.eq("del_flag", 0);
        List<LwgyBaseApartment> list = this.list(queryWrapper);
        return  list;
    }
    //获取上一级的list列表
    public List<LwgyBaseApartment> getUpOneLeveList(String pid){
        QueryWrapper<LwgyBaseApartment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", pid);//同级菜单
        queryWrapper.eq("del_flag", 0);
        List<LwgyBaseApartment> list = this.list(queryWrapper);
        return  list;
    }
    //获取list中的最大code和innercode(list中的code和innercode有空值会报错)
    public String[] getCodeByList(List<LwgyBaseApartment> list){
        LwgyBaseApartment sensorCode = list.stream().max(Comparator.comparing(LwgyBaseApartment ::getCode)).get();
        String code = sensorCode.getCode();
        LwgyBaseApartment sensorInnerCode = list.stream().max(Comparator.comparing(LwgyBaseApartment ::getInnerCode)).get();
        String innercode = sensorInnerCode.getInnerCode();
        String[] a = new String[2];
        a[0]=code;
        a[1]=innercode;
        return a;

    }


    @Override
    public void updateLwgyBaseApartment(LwgyBaseApartment lwgyBaseApartment) {
        LwgyBaseApartment entity = this.getById(lwgyBaseApartment.getId());
        lwgyBaseApartment.setRoomCoordinates(lwgyBaseApartment.getName());
        if (entity == null) {
            throw new JeecgBootException("未找到对应实体");
        }
        String old_pid = entity.getPid();
        String new_pid = lwgyBaseApartment.getPid();
        if (!old_pid.equals(new_pid)) {
            updateOldParentNode(old_pid);
            if (oConvertUtils.isEmpty(new_pid)) {
                lwgyBaseApartment.setPid(ILwgyBaseApartmentService.ROOT_PID_VALUE);
            }
            if (!ILwgyBaseApartmentService.ROOT_PID_VALUE.equals(lwgyBaseApartment.getPid())) {
                baseMapper.updateTreeNodeStatus(lwgyBaseApartment.getPid(), ILwgyBaseApartmentService.HASCHILD);
            }
        }
        baseMapper.updateById(lwgyBaseApartment);
    }
    @Override
    public void updateBedPrice(LwgyBaseApartment lwgyBaseApartment) {
        LwgyBaseApartment entity = this.getById(lwgyBaseApartment.getId());
        lwgyBaseApartment.setRoomCoordinates(lwgyBaseApartment.getName());
        if (entity == null) {
            throw new JeecgBootException("未找到对应实体");
        }
        String old_pid = entity.getPid();
        String new_pid = lwgyBaseApartment.getPid();
        if (!old_pid.equals(new_pid)) {
            updateOldParentNode(old_pid);
            if (oConvertUtils.isEmpty(new_pid)) {
                lwgyBaseApartment.setPid(ILwgyBaseApartmentService.ROOT_PID_VALUE);
            }
            if (!ILwgyBaseApartmentService.ROOT_PID_VALUE.equals(lwgyBaseApartment.getPid())) {
                baseMapper.updateTreeNodeStatus(lwgyBaseApartment.getPid(), ILwgyBaseApartmentService.HASCHILD);
            }
        }
        baseMapper.updateById(lwgyBaseApartment);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteLwgyBaseApartment(String id, String type) throws JeecgBootException {
        //查询选中节点下所有子节点一并删除
       /* if("room".){

        }*/
        id = this.queryTreeChildIds(id);
        System.out.println("id ===== " + id);
        if (id.indexOf(",") > 0) {
            StringBuffer sb = new StringBuffer();
            String[] idArr = id.split(",");
            for (String idVal : idArr) {
                if (idVal != null) {
                    LwgyBaseApartment lwgyBaseApartment = this.getById(idVal);
                    String pidVal = lwgyBaseApartment.getPid();
                    //查询此节点上一级是否还有其他子节点
                    List<LwgyBaseApartment> dataList = baseMapper.selectList(new QueryWrapper<LwgyBaseApartment>().eq("pid", pidVal).notIn("id", Arrays.asList(idArr)));
                    if ((dataList == null || dataList.size() == 0) && !Arrays.asList(idArr).contains(pidVal)
                            && !sb.toString().contains(pidVal)) {
                        //如果当前节点原本有子节点 现在木有了，更新状态
                        sb.append(pidVal).append(",");
                    }
                    if ("room".equals(lwgyBaseApartment.getType())) {
                        lwgyBaseBedMapper.deleteBatchPIds(Arrays.asList(idArr));
                    }
                }
            }
            //批量删除节点
            baseMapper.deleteBatchIds(Arrays.asList(idArr));
            //修改已无子节点的标识
            String[] pidArr = sb.toString().split(",");
            for (String pid : pidArr) {
                this.updateOldParentNode(pid);
            }
        } else {
            LwgyBaseApartment lwgyBaseApartment = this.getById(id);
            if (lwgyBaseApartment == null) {
                throw new JeecgBootException("未找到对应实体");
            }
            updateOldParentNode(lwgyBaseApartment.getPid());
            baseMapper.deleteById(id);
        }
    }

    @Override
    public List<LwgyBaseApartment> queryTreeListNoPage(QueryWrapper<LwgyBaseApartment> queryWrapper) {
        List<LwgyBaseApartment> dataList = baseMapper.selectList(queryWrapper);
        List<LwgyBaseApartment> mapList = new ArrayList<>();
        for (LwgyBaseApartment data : dataList) {
            String pidVal = data.getPid();
            //递归查询子节点的根节点
            if (pidVal != null && !"0".equals(pidVal)) {
                LwgyBaseApartment rootVal = this.getTreeRoot(pidVal);
                if (rootVal != null && !mapList.contains(rootVal)) {
                    mapList.add(rootVal);
                }
            } else {
                if (!mapList.contains(data)) {
                    mapList.add(data);
                }
            }
        }
        return mapList;
    }


    /**
     * 根据所传pid查询旧的父级节点的子节点并修改相应状态值
     *
     * @param pid
     */
    private void updateOldParentNode(String pid) {
        if (!ILwgyBaseApartmentService.ROOT_PID_VALUE.equals(pid)) {
            Long count = baseMapper.selectCount(new QueryWrapper<LwgyBaseApartment>().eq("pid", pid));
            if (count == null || count <= 1) {
                baseMapper.updateTreeNodeStatus(pid, ILwgyBaseApartmentService.NOCHILD);
            }
        }
    }

    /**
     * 递归查询节点的根节点
     *
     * @param pidVal
     * @return
     */
    private LwgyBaseApartment getTreeRoot(String pidVal) {
        LwgyBaseApartment data = baseMapper.selectById(pidVal);
        if (data != null && !"0".equals(data.getPid())) {
            return this.getTreeRoot(data.getPid());
        } else {
            return data;
        }
    }

    /**
     * 根据id查询所有子节点id
     *
     * @param ids
     * @return
     */
    private String queryTreeChildIds(String ids) {
        //获取id数组
        String[] idArr = ids.split(",");
        StringBuffer sb = new StringBuffer();
        for (String pidVal : idArr) {
            if (pidVal != null) {
                if (!sb.toString().contains(pidVal)) {
                    if (sb.toString().length() > 0) {
                        sb.append(",");
                    }
                    sb.append(pidVal);
                    this.getTreeChildIds(pidVal, sb);
                }
            }
        }
        return sb.toString();
    }

    /**
     * 递归查询所有子节点
     *
     * @param pidVal
     * @param sb
     * @return
     */
    private StringBuffer getTreeChildIds(String pidVal, StringBuffer sb) {
        List<LwgyBaseApartment> dataList = baseMapper.selectList(new QueryWrapper<LwgyBaseApartment>().eq("pid", pidVal));
        if (dataList != null && dataList.size() > 0) {
            for (LwgyBaseApartment tree : dataList) {
                if (!sb.toString().contains(tree.getId())) {
                    sb.append(",").append(tree.getId());
                }
                this.getTreeChildIds(tree.getId(), sb);
            }
        }
        return sb;
    }

    /**
     * 查询下一级的子节点
     *
     * @param id
     * @return ids
     */
    public String getChildIds(String id) {
        List<String> childIds = lwgyBaseApartmentMapper.getChildIds(id);
        if (childIds.size() > 0) {
            String ids = "";
            for (String childId : childIds) {
                ids = ids + childId + ",";
            }
            return ids;
        }
        return "";
    }

    /**
     * 通过pid获取最大内码
     *
     * @param pid
     * @return
     */
    @Override
    public String get_maxInnerCode(String pid) {
        String innerCode = lwgyBaseApartmentMapper.get_maxInnerCode(pid);
        return innerCode;
    }

    /**
     * 获取父节点的内码
     *
     * @param id
     * @return
     */
    public String get_parentInnerCode(String id) {
        String innerCode = lwgyBaseApartmentMapper.get_parentInnerCode(id);
        return innerCode;
    }

    /**
     * 获取父节点的级别
     *
     * @param pid
     * @return
     */
    @Override
    public Integer getLevel(String pid) {
        LwgyBaseApartment apartment = lwgyBaseApartmentMapper.getLevel(pid);
        if (apartment.getLevel() == null) {
            String type = apartment.getType();
            switch (type) {
                case "school":
                    lwgyBaseApartmentMapper.updateLevel(pid, "1");
                    return 1;
                case "campus":
                    lwgyBaseApartmentMapper.updateLevel(pid, "2");
                    return 2;
                case "faculty":
                    lwgyBaseApartmentMapper.updateLevel(pid, "3");
                    return 3;
                case "building":
                    lwgyBaseApartmentMapper.updateLevel(pid, "4");
                    return 4;
                case "unit":
                    lwgyBaseApartmentMapper.updateLevel(pid, "5");
                    return 5;
                case "layer":
                    lwgyBaseApartmentMapper.updateLevel(pid, "6");
                    return 6;
                case "room":
                    lwgyBaseApartmentMapper.updateLevel(pid, "7");
                    return 7;
            }
        }
        return apartment.getLevel();
    }


    /**
     * @param pid
     * @return
     * @remark 创建inner_code, 传入pid，
     * 如果当前没有子节点，生成第一个inner_code
     * 如果存在子节点，返回最大inner_code+1
     */
    @Override
    public String createInnerCode(String pid) {
        //String level = getLevel(pid);
        String maxInnerCode = get_maxInnerCode(pid);
        if (maxInnerCode == null) {
            if (pid.equals("0")) {
                return "001";
            }
            String parentInnerCode = get_parentInnerCode(pid);
            parentInnerCode += "0001";
            return parentInnerCode;
        } else {
            String suffix = maxInnerCode.substring(0, maxInnerCode.length() - 4);
            String prefix = maxInnerCode.substring(maxInnerCode.length() - 4);
            int innerCode = Integer.parseInt(prefix) + 1;
            String s = String.format("%0" + 4 + "d", innerCode);
            s = suffix + s;
            return s;
        }
    }

    /**
     * @param pid
     * @return 返回最大inner_code
     * 如若inner_code不存在则创建inner_code
     * @remark 创建inner_code, 传入pid，
     * 如果当前没有子节点，生成第0个inner_code
     * 如果存在子节点，返回最大inner_code
     */
    @Override
    public String createInnerCode2(String pid) {

        String maxInnerCode = get_maxInnerCode(pid);
        if (maxInnerCode == null) {
            if (pid.equals("0")) {
                return "001";
            }
            String parentInnerCode = get_parentInnerCode(pid);
            parentInnerCode += "0000";
            return parentInnerCode;
        } else {
            return maxInnerCode;
        }
    }


    /**
     * 为减少代码冗余，将各层级的创建抽离出来，这么做会影响系统的执行效率（待优化）【尽可能做到少提交，进而减轻数据库的压力，系统运行自然变快】
     * 批量创建楼宇、单元、楼层、房间
     *
     * @param lwgyApartmentCustom
     */
    @Override
    @Deprecated
    public void create_building(LwgyApartmentCustom lwgyApartmentCustom) {
        LwgyBaseApartment HasChild = new LwgyBaseApartment();
        HasChild.setId(lwgyApartmentCustom.getPid());
        HasChild.setHasChild("1");
        updateHasChild(HasChild);//创建楼宇时如果父节点下没有子节点，创建楼宇后会出现页面不显示的情况。需要这里手动将楼宇的上级目录的HasChild设为1
        String innerCode = createInnerCode2(lwgyApartmentCustom.getPid());
        List<LwgyBaseApartment> building_list = new ArrayList<>();
        for (int i = 0; i < lwgyApartmentCustom.getBuildingNum(); i++) {//根据用户输入的楼宇数量，批量创建楼宇信息
            innerCode = getInnerCodeByList2(innerCode);
            LwgyBaseApartment lwgyBaseApartment_building = new LwgyBaseApartment();
            lwgyBaseApartment_building.setPid(lwgyApartmentCustom.getPid());
            lwgyBaseApartment_building.setType("building");
            lwgyBaseApartment_building.setHasChild("1");
            lwgyBaseApartment_building.setLevel(4);
            lwgyBaseApartment_building.setInnerCode(innerCode);
            int num = Integer.parseInt(innerCode.substring(innerCode.length() - 4));
            lwgyBaseApartment_building.setName(num + "号楼");
            building_list.add(lwgyBaseApartment_building);
        }
        saveBatch(building_list);//将创建好的楼宇信息一次性插入数据库
        Integer unitNum = lwgyApartmentCustom.getUnitNum();
        for (LwgyBaseApartment lwgyBaseApartment : building_list) {//遍历新建楼宇创建单元
            lwgyApartmentCustom.setPid(lwgyBaseApartment.getId());
            create_unit(lwgyApartmentCustom);
        }

    }


    /**
     * 创建楼宇、单元、楼层、房间增强版
     */
    @Override
    public void everything(LwgyApartmentCustom lwac) {
        LwgyBaseApartment HasChild = new LwgyBaseApartment();
        String pid = lwac.getPid();
        HasChild.setId(pid);
        HasChild.setHasChild("1");
        updateHasChild(HasChild);//创建楼宇时如果父节点下没有子节点，创建楼宇后会出现页面不显示的情况。需要这里手动将楼宇的上级目录的HasChild设为1
        Integer buildingNum = lwac.getBuildingNum();//楼宇数量
        Integer unitNum = lwac.getUnitNum();//单元数量
        Integer layerNum = lwac.getLayerNum();//楼层数量
        Set<LwgyBaseApartment> everythingSet = new HashSet<>(16);//用来保存构建的所有对象
        Set<LwgyBaseApartment> buildingSet = null;//保存所有楼宇对象
        Set<LwgyBaseApartment> unitSet = null;//保存单元对象
        Set<LwgyBaseApartment> layerSet = new HashSet<>(5);//楼层
        Set<LwgyBaseApartment> eastRoomSet = new HashSet<>(20);  //东面房间
        Set<LwgyBaseApartment> westRoomSet = new HashSet<>(20);//西面房间
        Set<LwgyBaseApartment> southRoomSet = new HashSet<>(20);//南面房间
        Set<LwgyBaseApartment> northRoomSet = new HashSet<>(20);//北面房间
//        JSONObject formData = new JSONObject();
//        formData.put("parentId", pid);
//        String[] codeArray = (String[]) FillRuleUtil.executeRuleSchool(FillRuleConstant.DEPART, formData);
//        lwac.setSysOrgCode(codeArray[0]);
//        lwac.setDelFlag("0");
//        baseMapper.insert(lwac);
        if (buildingNum != null && buildingNum > 0) {//当前端传过来的参数条件成立
            Map<String, Set<LwgyBaseApartment>> buildingSetForMap = buildApartEntity(lwac, everythingSet, null, buildingNum, "building", 4, "号楼");//构建楼宇实体
            buildingSet = buildingSetForMap.get("apartSet");//楼宇实体集合
            everythingSet = buildingSetForMap.get("everythingSet");
        }
        if (unitNum != null && unitNum >= 0) {//学校不区分单元时，默认创建一单元
            if (unitNum == 0) {
                unitNum = 1;
            }
            Map<String, Set<LwgyBaseApartment>> unitSetForMap = buildApartEntity(lwac, everythingSet, buildingSet, unitNum, "unit", 5, "单元");
            unitSet = unitSetForMap.get("apartSet");
            everythingSet = unitSetForMap.get("everythingSet");
        }
        if (layerNum != null && layerNum > 0) {
            Map<String, Set<LwgyBaseApartment>> layerSetForMap = buildApartEntity(lwac, everythingSet, unitSet, layerNum, "layer", 6, "层");
            layerSet = layerSetForMap.get("apartSet");
            everythingSet = layerSetForMap.get("everythingSet");
        }
        //取东西南北面房间数量
        Integer eastRoomNum = lwac.getEastRoomNum();
        Integer westRoomNum = lwac.getWestRoomNum();
        Integer southRoomNum = lwac.getSouthRoomNum();
        Integer northRoomNum = lwac.getNorthRoomNum();
        Integer bedsNum = lwac.getBedsNum();
        if (layerSet.isEmpty()) {//在楼层上单独创建房间
            String id = lwac.getPid();
            String innerCode = createInnerCode2(id);
            String roomSex = lwac.getRoomSex();
            String name = getById(id).getName();
            String roomCoordinates = getById(id).getRoomCoordinates();
            Map<String, Set<LwgyBaseApartment>> setMap = batchCreateRoom3(name, everythingSet, eastRoomSet, westRoomSet, southRoomSet, northRoomSet, eastRoomNum, westRoomNum, northRoomNum, southRoomNum, id, innerCode, roomSex, bedsNum);
            eastRoomSet = setMap.get("eastRoomSet");
            westRoomSet = setMap.get("westRoomSet");
            southRoomSet = setMap.get("southRoomSet");
            northRoomSet = setMap.get("northRoomSet");
        } else {
            for (LwgyBaseApartment lwgyBaseApartment : layerSet) {//遍历所有楼层，在每一层楼上创建东西南北面房间
                String name = "";
                lwgyBaseApartment.setRoomCoordinates(lwgyBaseApartment.getName());
                String roomCoordinates = lwgyBaseApartment.getRoomCoordinates();
                String id = lwgyBaseApartment.getId();
                String innerCode = lwgyBaseApartment.getInnerCode() + "0000";
                String roomSex = lwac.getRoomSex();
                name = lwgyBaseApartment.getName();
                Map<String, Set<LwgyBaseApartment>> setMap = batchCreateRoom3(name, everythingSet, eastRoomSet, westRoomSet, southRoomSet, northRoomSet, eastRoomNum, westRoomNum, northRoomNum, southRoomNum, id, innerCode, roomSex, bedsNum);
                eastRoomSet = setMap.get("eastRoomSet");
                westRoomSet = setMap.get("westRoomSet");
                southRoomSet = setMap.get("southRoomSet");
                northRoomSet = setMap.get("northRoomSet");
            }
        }
        saveBatch(everythingSet);//一次性提交所有实体，减少对数据库的访问
        //Integer bedsNum = lwac.getBedsNum();
        if (bedsNum != null && bedsNum > 0) {
            String bedPrice = lwac.getBedsPrice();
            batchCreateBed(lwac, eastRoomSet, bedsNum, bedPrice);//创建东面房间的床位
            batchCreateBed(lwac, westRoomSet, bedsNum, bedPrice);//创建西面房间的床位
            batchCreateBed(lwac, southRoomSet, bedsNum, bedPrice);//创建南面房间的床位
            batchCreateBed(lwac, northRoomSet, bedsNum, bedPrice);//创建北面房间的床位
        }

    }

    /**
     * 参数严重冗余（待优化）
     *
     * @param name
     * @param everythingSet
     * @param eastRoomSet
     * @param westRoomSet
     * @param southRoomSet
     * @param northRoomSet
     * @param eastRoomNum
     * @param westRoomNum
     * @param northRoomNum
     * @param southRoomNum
     * @param id
     * @param innerCode
     * @param roomSex
     * @return
     */
    private Map<String, Set<LwgyBaseApartment>>
    batchCreateRoom3(String name, Set<LwgyBaseApartment> everythingSet, Set<LwgyBaseApartment> eastRoomSet,
                     Set<LwgyBaseApartment> westRoomSet, Set<LwgyBaseApartment> southRoomSet,
                     Set<LwgyBaseApartment> northRoomSet, Integer eastRoomNum,
                     Integer westRoomNum, Integer northRoomNum, Integer southRoomNum,
                     String id, String innerCode, String roomSex, Integer bedsNum ) {
        String roomCoordinates;
        if (name.trim().length() <= 2) {//取楼层的数字位作为房间名称的前缀（例5层 取name为5 房间名称后缀从1开始，中间用0补齐两位哦 构成501）
            name = name.substring(0, 1);
        } else {
            name = name.substring(0, 2);
        }
        if (eastRoomNum != null && eastRoomNum > 0) {
            Map<String, Object> eastRoomSetForMap = batchCreateRoom(everythingSet, eastRoomSet, eastRoomNum, id, innerCode, name, roomSex, "east", bedsNum);
            everythingSet = (Set<LwgyBaseApartment>) eastRoomSetForMap.get("everythingSet");
            eastRoomSet = (Set<LwgyBaseApartment>) eastRoomSetForMap.get("roomSet");
            innerCode = (String) eastRoomSetForMap.get("innerCode");
            roomCoordinates = name;
        }
        if (westRoomNum != null && westRoomNum > 0) {
            Map<String, Object> westRoomSetForMap = batchCreateRoom(everythingSet, westRoomSet, westRoomNum, id, innerCode, name, roomSex, "west", bedsNum);
            everythingSet = (Set<LwgyBaseApartment>) westRoomSetForMap.get("everythingSet");
            westRoomSet = (Set<LwgyBaseApartment>) westRoomSetForMap.get("roomSet");
            innerCode = (String) westRoomSetForMap.get("innerCode");
            roomCoordinates = name;
        }
        if (southRoomNum != null && southRoomNum > 0) {
            Map<String, Object> southRoomSetForMap = batchCreateRoom(everythingSet, southRoomSet, southRoomNum, id, innerCode, name, roomSex, "south", bedsNum);
            everythingSet = (Set<LwgyBaseApartment>) southRoomSetForMap.get("everythingSet");
            southRoomSet = (Set<LwgyBaseApartment>) southRoomSetForMap.get("roomSet");
            innerCode = (String) southRoomSetForMap.get("innerCode");
            roomCoordinates = name;
        }
        if (northRoomNum != null && northRoomNum > 0) {
            Map<String, Object> northRoomSetForMap = batchCreateRoom(everythingSet, northRoomSet, northRoomNum, id, innerCode, name, roomSex, "north", bedsNum);
            everythingSet = (Set<LwgyBaseApartment>) northRoomSetForMap.get("everythingSet");
            northRoomSet = (Set<LwgyBaseApartment>) northRoomSetForMap.get("roomSet");

        }
        Map<String, Set<LwgyBaseApartment>> map = new HashMap<>(4);
        map.put("eastRoomSet", eastRoomSet);
        map.put("westRoomSet", westRoomSet);
        map.put("southRoomSet", southRoomSet);
        map.put("northRoomSet", northRoomSet);
        map.put("everythingSet", everythingSet);

        return map;
    }

    /**
     * method 批量创建床位
     *
     * @param lwac     自定义公寓属性的数量
     * @param roomSet  房间集合
     * @param bedsNum  床位数量
     * @param bedPrice 床位价格
     */
    private void batchCreateBed(LwgyApartmentCustom lwac, Set<LwgyBaseApartment> roomSet, Integer bedsNum, String bedPrice) {
        String innerCode;
        String id;
        Set<LwgyBaseBed> bedSet = new HashSet<>(50);
        if (roomSet.isEmpty()) {//对象为空返回true,单独创建房间时，

            return;
        } else {
            for (LwgyBaseApartment baseApartment : roomSet) {//创建房间的同时创建床位
                innerCode = baseApartment.getInnerCode() + "0000";
                id = baseApartment.getId();
                bedSet = traversalBed(bedsNum, innerCode, id, bedSet, bedPrice);
            }
        }
        lwgyBaseBedService.saveBatch(bedSet);
    }

    /**
     * 遍历床位实体加入set集合
     *
     * @param bedsNum   床位数量
     * @param innerCode 内码
     * @param id
     * @param bedSet    床位实体集合
     * @param bedPrice  床位价格
     * @return Set<LwgyBaseBed> 返回床位实体集合
     */
    private Set<LwgyBaseBed> traversalBed(Integer bedsNum, String innerCode, String id, Set<LwgyBaseBed> bedSet, String bedPrice) {
        for (int i = 0; i < bedsNum; i++) {
            LwgyBaseBed lwgyBaseBed = new LwgyBaseBed();
            lwgyBaseBed.setRoomId(id);
            lwgyBaseBed.setBedPrice(bedPrice);
            innerCode = getInnerCodeByList2(innerCode);
            lwgyBaseBed.setBedCode(innerCode);
//            lwgyBaseBed.setName(generateBedCode(innerCode));
            int num = Integer.parseInt(innerCode.substring(innerCode.length() - 4));
            lwgyBaseBed.setName(String.valueOf(num));
            bedSet.add(lwgyBaseBed);
        }
        return bedSet;
    }

    /**
     * @param everythingSet   所有公寓实体的集合
     * @param eastRoomSet     东面房间的集合
     * @param roomNum         东面房间数量
     * @param id
     * @param innerCode       内码
     * @param name
     * @param roomSex         房间性别
     * @param roomOrientation 房间朝向（东南西北【数据库内存的英文east为东】）
     * @return Map<String, Object> 返回所有实体集合 当前房间集合和当前最大内码
     */
    private Map<String, Object> batchCreateRoom(Set<LwgyBaseApartment> everythingSet, Set<LwgyBaseApartment> eastRoomSet, Integer roomNum, String id, String innerCode, String name, String roomSex, String roomOrientation, Integer bedsNum) {
        LwgyBaseApartment lwba;
        for (int i = 0; i < roomNum; i++) {
            lwba = new LwgyBaseApartment();
            lwba.setId(String.valueOf(snowflake.snowflakeId()));
            lwba.setPid(id);
            lwba.setType("room");
            lwba.setRoomType("hotel_room");
            lwba.setRoomSex(roomSex);
            lwba.setHasChild("0");
            lwba.setLevel(7);
            lwba.setBedsNum(bedsNum);
            lwba.setRoomOrientation(roomOrientation);
            innerCode = getInnerCodeByList2(innerCode);
            lwba.setInnerCode(innerCode);

            int num = Integer.parseInt(innerCode.substring(innerCode.length() - 4));
            lwba.setName(name + String.format("%0" + 2 + "d", num));
            lwba.setRoomCoordinates(name + String.format("%0" + 2 + "d", num));
            eastRoomSet.add(lwba);
        }
        everythingSet.addAll(eastRoomSet);
        Map<String, Object> map = new HashMap<>(4);
        map.put("everythingSet", everythingSet);
        map.put("roomSet", eastRoomSet);
        map.put("innerCode", innerCode);
        return map;
    }

    /***
     *method 构建公寓实体
     *
     * @param lwac 自定义的公寓数量实体
     * @param everythingSet 存放将要构建的所有公寓实体
     * @param set 上一级实体
     * @param apartNum 公寓数量
     * @param type 类型
     * @param level 级别
     * @param name 名称
     * @return Map<String, Set < LwgyBaseApartment>>
     *     主要存放了两个实体，一个是当前实体集合和所有公寓实体的集合
     */
    private Map<String, Set<LwgyBaseApartment>> buildApartEntity(LwgyApartmentCustom lwac, Set<LwgyBaseApartment> everythingSet, Set<LwgyBaseApartment> set, Integer apartNum, String type, int level, String name) {
        Set<LwgyBaseApartment> apartSet = new HashSet<>(16);
        String innerCode;
        String code;
        if (set == null) {
            innerCode = createInnerCode2(lwac.getPid());
            code="";
            apartSet = traversalApart(lwac.getPid(), apartNum, type, level, name, apartSet, innerCode);
        } else if (apartNum == null || apartNum <= 0) {

        } else {
            for (LwgyBaseApartment lwgyBaseApartment : set) {
                String id = lwgyBaseApartment.getId();
                innerCode = lwgyBaseApartment.getInnerCode() + "0000";
                if ("room".equals(type)) {
                    name = lwgyBaseApartment.getName();
                }
                apartSet = traversalApart(id, apartNum, type, level, name, apartSet, innerCode);
            }
        }
        everythingSet.addAll(apartSet);

        Map<String, Set<LwgyBaseApartment>> map = new HashMap<>(16);
        map.put("everythingSet", everythingSet);
        map.put("apartSet", apartSet);
        return map;
    }

    /***
     *
     * @param pid 父id
     * @param apartNum 公寓数量（可能为楼宇、单元、楼层等）的数量
     * @param type   类型
     * @param level   级别
     * @param name   名称
     * @param apartSet 当前公寓集合
     * @param innerCode 内码
     * @return
     */
    private Set<LwgyBaseApartment> traversalApart(String pid, Integer apartNum, String type, int level, String name, Set<LwgyBaseApartment> apartSet, String innerCode) {
        LwgyBaseApartment lwba;
        if ("room".equals(type)) {
            if (name.trim().length() <= 2) {
                name = name.substring(0, 1);
            } else {
                name = name.substring(0, 2);
            }
        }
        for (int i = 0; i < apartNum; i++) {
            lwba = new LwgyBaseApartment();
            lwba.setId(String.valueOf(snowflake.snowflakeId()));
            lwba.setPid(pid);
            lwba.setType(type);
            lwba.setHasChild("1");
            lwba.setLevel(level);
            innerCode = getInnerCodeByList2(innerCode);
            lwba.setInnerCode(innerCode);
            int num = Integer.parseInt(innerCode.substring(innerCode.length() - 4));
            if ("room".equals(type)) {
                lwba.setName(name + String.format("%0" + 2 + "d", num));
            } else {
                lwba.setName(num + name);
            }
            apartSet.add(lwba);
        }

        return apartSet;
    }


    @Test
    public void test1() {
        LwgyApartmentCustom lac = new LwgyApartmentCustom();
        lac.setPid("1374549138202955778");
        lac.setBuildingNum(2);
        lac.setUnitNum(2);
        lac.setLayerNum(2);
        lac.setEastRoomNum(1);
        lac.setWestRoomNum(1);
        lac.setSouthRoomNum(1);
        lac.setNorthRoomNum(1);
        lac.setBedsNum(4);
        //everything(lac);
    }

    /**
     * 修改公寓列表是否有子节点
     *
     * @param hasChild
     */
    private void updateHasChild(LwgyBaseApartment hasChild) {
        lwgyBaseApartmentMapper.updateHasChild(hasChild);
    }


    /**
     * 批量创建单元、楼层、房间
     *
     * @param lwgyApartmentCustom
     */
    @Override
    @Deprecated
    public void create_unit(LwgyApartmentCustom lwgyApartmentCustom) {
        List<LwgyBaseApartment> unit_list = new ArrayList<>();
        LwgyBaseApartment HasChild = new LwgyBaseApartment();
        HasChild.setId(lwgyApartmentCustom.getPid());
        HasChild.setHasChild("1");
        updateHasChild(HasChild);
        Integer unitNum = lwgyApartmentCustom.getUnitNum();
        if (unitNum <= 0) {//某些学校没有单元的概念，默认创建为1单元
            unitNum = 1;
        }
        String innerCode = createInnerCode2(lwgyApartmentCustom.getPid());
        for (int i = 0; i < unitNum; i++) {
            innerCode = getInnerCodeByList2(innerCode);
            LwgyBaseApartment lwgyBaseApartment = new LwgyBaseApartment();
            lwgyBaseApartment.setPid(lwgyApartmentCustom.getPid());
            lwgyBaseApartment.setType("unit");
            lwgyBaseApartment.setHasChild("1");
            lwgyBaseApartment.setLevel(5);
            lwgyBaseApartment.setInnerCode(innerCode);
            int num = Integer.parseInt(innerCode.substring(innerCode.length() - 4));
            lwgyBaseApartment.setName(num + "单元");
            unit_list.add(lwgyBaseApartment);
            //addLwgyBaseApartment(lwgyBaseApartment);
        }
        saveBatch(unit_list, unit_list.size());
        for (LwgyBaseApartment lwgyBaseApartment : unit_list) {
            lwgyApartmentCustom.setPid(lwgyBaseApartment.getId());
            create_layer(lwgyApartmentCustom);
        }


    }

    /**
     * 批量创建楼层、房间
     *
     * @param lwgyApartmentCustom
     */
    @Override
    @Deprecated
    public void create_layer(LwgyApartmentCustom lwgyApartmentCustom) {
        List<LwgyBaseApartment> layer_list = new ArrayList<>();
        LwgyBaseApartment HasChild = new LwgyBaseApartment();
        HasChild.setId(lwgyApartmentCustom.getPid());
        HasChild.setHasChild("1");
        updateHasChild(HasChild);
        Integer layerNum = lwgyApartmentCustom.getLayerNum();
        if (layerNum <= 0) {
            layerNum = 1;
        }
        String innerCode = createInnerCode2(lwgyApartmentCustom.getPid());
        for (int i = 0; i < layerNum; i++) {
            innerCode = getInnerCodeByList2(innerCode);
            LwgyBaseApartment lwgyBaseApartment_layer = new LwgyBaseApartment();
            lwgyBaseApartment_layer.setPid(lwgyApartmentCustom.getPid());
            lwgyBaseApartment_layer.setType("layer");
            lwgyBaseApartment_layer.setHasChild("1");
            lwgyBaseApartment_layer.setLevel(6);
            lwgyBaseApartment_layer.setInnerCode(innerCode);
            int num_layer = Integer.parseInt(innerCode.substring(innerCode.length() - 4));
            lwgyBaseApartment_layer.setName(num_layer + "层");
            layer_list.add(lwgyBaseApartment_layer);
        }
        saveBatch(layer_list, layer_list.size());
        for (LwgyBaseApartment lwgyBaseApartment : layer_list) {
            lwgyApartmentCustom.setPid(lwgyBaseApartment.getId());
            create_room(lwgyApartmentCustom);
        }
    }


    /**
     * 批量创建房间
     *
     * @param lwgyApartmentCustom
     */
    @Override
    @Deprecated
    public void create_room(LwgyApartmentCustom lwgyApartmentCustom) {
        List<LwgyBaseApartment> room_list = new ArrayList<>();
        LwgyBaseApartment HasChild = new LwgyBaseApartment();
        HasChild.setId(lwgyApartmentCustom.getPid());
        HasChild.setHasChild("1");
        updateHasChild(HasChild);
        Integer roomSunnySide = lwgyApartmentCustom.getRoomSunnySide();
        String innerCode = createInnerCode2(lwgyApartmentCustom.getPid());
        String name = getById(lwgyApartmentCustom.getPid()).getName();
        if (name.trim().length() <= 2) {
            name = name.substring(0, 1);
        } else {
            name = name.substring(0, 2);
        }
        //循环创建阳面房间
        for (int k = 0; k < roomSunnySide; k++) {
            innerCode = getInnerCodeByList2(innerCode);
            LwgyBaseApartment lwgyBaseApartment_RoomSunny = new LwgyBaseApartment();
            lwgyBaseApartment_RoomSunny.setPid(lwgyApartmentCustom.getPid());
            lwgyBaseApartment_RoomSunny.setType("room");
            lwgyBaseApartment_RoomSunny.setRoomType("hotel_room");
            lwgyBaseApartment_RoomSunny.setHasChild("1");
            lwgyBaseApartment_RoomSunny.setLevel(7);
            lwgyBaseApartment_RoomSunny.setInnerCode(innerCode);
            int num_RoomSunny = Integer.parseInt(innerCode.substring(innerCode.length() - 4));
            lwgyBaseApartment_RoomSunny.setName(name + String.format("%0" + 2 + "d", num_RoomSunny));
            lwgyBaseApartment_RoomSunny.setRoomOrientation("1");
            lwgyBaseApartment_RoomSunny.setRoomSex(lwgyApartmentCustom.getRoomSex());
            room_list.add(lwgyBaseApartment_RoomSunny);
        }
        Integer roomNightSideNum = lwgyApartmentCustom.getRoomNightSideNum();
        //循环创建阴面房间
        for (int k = 0; k < roomNightSideNum; k++) {
            LwgyBaseApartment lwgyBaseApartment_RoomNight = new LwgyBaseApartment();
            innerCode = getInnerCodeByList2(innerCode);
            lwgyBaseApartment_RoomNight.setPid(lwgyApartmentCustom.getPid());
            lwgyBaseApartment_RoomNight.setType("room");
            lwgyBaseApartment_RoomNight.setRoomType("hotel_room");
            lwgyBaseApartment_RoomNight.setHasChild("1");
            lwgyBaseApartment_RoomNight.setLevel(7);
            lwgyBaseApartment_RoomNight.setInnerCode(innerCode);
            int num_RoomNight = Integer.parseInt(innerCode.substring(innerCode.length() - 4));
            lwgyBaseApartment_RoomNight.setName(name + String.format("%0" + 2 + "d", num_RoomNight));
            lwgyBaseApartment_RoomNight.setRoomOrientation("2");
            lwgyBaseApartment_RoomNight.setRoomSex(lwgyApartmentCustom.getRoomSex());
            room_list.add(lwgyBaseApartment_RoomNight);
        }
        //批量插入到数据库
        if (room_list.size() > 0) {
            saveBatch(room_list);
        }
        for (LwgyBaseApartment lwgyBaseApartment : room_list) {
            lwgyApartmentCustom.setPid(lwgyBaseApartment.getId());
            lwgyBaseBedService.create_bed(lwgyApartmentCustom);

        }
    }

    @Override
    public Integer getLevelByType(String type) {
        Integer level = 1;
        switch (type) {
            case "school":
                level = 1;
                break;
            case "campus":
                level = 2;
                break;
            case "faculty":
                level = 3;
                break;
            case "building":
                level = 4;
                break;
            case "unit":
                level = 5;
                break;
            case "layer":
                level = 6;
                break;
            case "room":
                level = 7;
                break;
        }
        return level;
    }

    public String getMaxInnerCodeByList(List<LwgyBaseApartment> lwgyBaseApartments, String pid) {
        List<LwgyBaseApartment> list = new ArrayList<>();
        for (LwgyBaseApartment lwgyBaseApartment : lwgyBaseApartments) {
            String pid1 = lwgyBaseApartment.getPid();
            if (pid.equals(pid1)) {
                list.add(lwgyBaseApartment);
            }
        }
        Collections.sort(list);
        LwgyBaseApartment lwgyBaseApartment = list.get(1);
        int i = Integer.parseInt(lwgyBaseApartment.getInnerCode());
        i++;
        return i + "";
    }

    /**
     * 传入当前的inner_code返回inner_code + 1
     *
     * @param inner_code
     * @return
     */
    @Override
    public String getInnerCodeByList2(String inner_code) {
        String suffix = inner_code.substring(0, inner_code.length() - 4);
        String prefix = inner_code.substring(inner_code.length() - 4);
        int innerCode = Integer.parseInt(prefix) + 1;
        String s = String.format("%0" + 4 + "d", innerCode);
        s = suffix + s;
        return s;
    }
    /**
     * 公寓信息全部缓存

    public static final String APARTMENT_CACHE = "apartment:cache:alldata";
     */
    @Cacheable(value ="apartment:cache:alldata")
    @Override
    public List<LwgyBaseApartmentTreeList> queryTreeList(String type, String id) {
        LambdaQueryWrapper<LwgyBaseApartment> query = new LambdaQueryWrapper<>();
        query.eq(LwgyBaseApartment::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
        if (oConvertUtils.isNotEmpty(type) && oConvertUtils.isNotEmpty(id)) {
            query.eq(LwgyBaseApartment::getType, type);
            query.eq(LwgyBaseApartment::getId, id);
        }
        query.orderByAsc(LwgyBaseApartment::getInnerCode);
        //query.orderByAsc(School::getDepartOrder);
        List<LwgyBaseApartment> list = this.list(query);
        // 调用wrapTreeDataToTreeList方法生成树状数据
        List<LwgyBaseApartmentTreeList> listResult = FindsApartmentChildrenUtil.wrapTreeDataToTreeList(list);
        return listResult;
    }

    @Override
    public List<String> getRoomType(String layerId) {
        return lwgyBaseApartmentMapper.getRoomType(layerId);
    }

    @Override
    public List<String> getChildrenIdByPid(String unitId) {
        return lwgyBaseApartmentMapper.getChildrenIdByPid(unitId);
    }


    /**
     * 将内码转为可读的床位code
     *
     * @param innerCode
     * @return
     */
    @Override
    public String generateBedCode(String innerCode) {
        try {
            Integer.parseInt(innerCode);
        } catch (Exception e) {
            return null;
        }
        String prefix = innerCode.substring(0, 3);
        System.out.println("sub = " + prefix);
        prefix = prefix.substring(1, 3);
        innerCode = innerCode.substring(3);
        int length = innerCode.length();
        for (int i = 0; i < length; i += 4) {
            String content = innerCode.substring(i, i + 4);
            content = content.substring(2, 4);
            prefix += "-";
            prefix += content;
        }
        return prefix;
    }

    @Test
    public void test() {
        String inner_code = "001";
        String suffix = inner_code.substring(0, inner_code.length() - 3);
        String prefix = inner_code.substring(inner_code.length() - 3);
        int innerCode = Integer.parseInt(prefix) + 1;
        String s = String.format("%0" + 3 + "d", innerCode);
        s = suffix + s;
        System.out.println(s);

    }
    @Override
    public List getFjBaseInfo() {
        return lwgyBaseApartmentMapper.getFjBaseInfo();
    }

    protected static CopyOnWriteArrayList<LwgyBaseApartment> lwgyBaseApartmentList = new CopyOnWriteArrayList<>();

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void copyApartment(HashMap<String, Object> map) {
        String type = (String) map.get("type");
        String id = (String) map.get("pid");
        String name = (String) map.get("name");

        lwgyBaseApartmentList.clear();
        LwgyBaseApartment lwgyBaseApartmentRoot = lwgyBaseApartmentMapper.selectById(id);//查询选中的根节点具体信息
        lwgyBaseApartmentRoot.setName(name);//修改为用户设置的名称
        lwgyBaseApartmentList.add(lwgyBaseApartmentRoot);//添加到集合中
        List<LwgyBaseApartment> lwgyBaseApartments = findchildList(id);//查找子节点
        List<LwgyBaseApartment> room = lwgyBaseApartments.stream().filter(lwgyBaseApartment -> lwgyBaseApartment.getType().equals("room")).collect(Collectors.toList());//找出所有房间
        List<String> strings = new ArrayList<>();
        for (LwgyBaseApartment lwgyBaseApartment : room) {
            String roomId = lwgyBaseApartment.getId();
            strings.add(roomId);
        }
        //lwgyBaseApartments.forEach(System.out::println);
        for (LwgyBaseApartment lwgyBaseApartment : lwgyBaseApartments) {//遍历修改id 与 pid的值完成复制操作
            String oldId = lwgyBaseApartment.getId();//获取之前的id
            String snowflakeId = String.valueOf(snowflake.snowflakeId());//得到新的分布式id
            lwgyBaseApartment.setId(snowflakeId);//替换老的id
            lwgyBaseApartments.stream().filter(lwgyBaseApartment1 ->
                    lwgyBaseApartment1.getPid().equals(oldId)).forEach(lwgyBaseApartment1 ->//根据老的父id找到所有子节点
                    lwgyBaseApartment1.setPid(snowflakeId));//将pid替换为新的父id
            if ("layer".equals(type)) {//如果是楼层，需要根据楼层名称修改房间名称，例如7层的房间名为701、702
                String num = Pattern.compile("[^0-9]").matcher(name).replaceAll("");//提取数字部分
                lwgyBaseApartments.stream().filter(lwgyBaseApartment1 ->
                        lwgyBaseApartment1.getType().equals("room")).forEach(lwgyBaseApartment1 ->
                        lwgyBaseApartment1.setName(num + lwgyBaseApartment1
                                .getName().substring(1)));
            }
        }
        //入库
        saveBatch(lwgyBaseApartments);
        //*************复制楼宇房间完成*******/

        QueryWrapper<LwgyBaseBed> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("room_id", strings);
        List<LwgyBaseBed> bedList = lwgyBaseBedMapper.selectList(queryWrapper);
        List<LwgyBaseApartment> newRoom = lwgyBaseApartments.stream()
                .filter(lwgyBaseApartment -> lwgyBaseApartment.getType().equals("room")).collect(Collectors.toList());//找出所有房间
        HashMap<String, String> roomIdMap = new HashMap<>(50);
        for (int i = 0; i < newRoom.size(); i++) {
            roomIdMap.put(room.get(i).getId(), newRoom.get(i).getId());
        }
        roomIdMap.forEach((oldId, newId) -> {
            bedList.stream().filter(bed -> bed.getRoomId().equals(oldId)).forEach(bed -> bed.setRoomId(newId));
        });
        bedList.stream().filter(bed -> oConvertUtils.isNotEmpty(bed)).forEach(bed -> bed.setStudentId(""));//不能复制原来的学生，清空studentId
        bedList.stream().forEach(bed -> bed.setId(String.valueOf(snowflake.snowflakeId())));//重置id
        //入库
        lwgyBaseBedService.saveBatch(bedList);
        //bedList.forEach(System.out::println);
        //lwgyBaseApartments.forEach(System.out::println);


    }


    @Override
    public String getMaxBedName(String pid) {
        String maxBedName = lwgyBaseBedMapper.getMaxBedName(pid);
        if (oConvertUtils.isEmpty(maxBedName)) {
            return "00";
        }
        return maxBedName;
    }

    @Override
    public List<LwgyBaseApartment> getTreeChild(String pid) {
        List<LwgyBaseApartment> apartmentList;
        String workNo="";

        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        List<String> role = lwgyBaseBedService.getRoleById(sysUser.getId());
        if (role.contains("fdy")) {//不是管理员，显示辅导员所在班级的学生

            String apartmentType;
            if(pid.equals("0")){
                QueryWrapper<LwgyBaseApartment> queryWrapper = new QueryWrapper<>();
                queryWrapper.select("id", "name");
                queryWrapper.eq("pid", pid);
                apartmentList = lwgyBaseApartmentMapper.selectList(queryWrapper);//获取数据
            }else{
                LwgyBaseApartment lwgyBaseApartment = lwgyBaseApartmentMapper.getLevel(pid);
                apartmentType = lwgyBaseApartment.getType();
                System.out.print("apartmentTypem"+apartmentType);
                workNo =  sysUser.getWorkNo();
                apartmentList = lwgyBaseApartmentMapper.selectListByPidAndWork(pid,workNo,apartmentType);
            }


        }else{
            QueryWrapper<LwgyBaseApartment> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("id", "name");
//          queryWrapper.orderByAsc("name");
            queryWrapper.eq("pid", pid);

            apartmentList = lwgyBaseApartmentMapper.selectList(queryWrapper);//获取数据
        }

        return apartmentList;
    }



    @Override
    public List<Map<String, Object>> getEveryBuildPersonNumBer(String workNo) {
        return lwgyBaseApartmentMapper.getEveryBuildPersonNumBer(workNo);
    }

    @Override
    public List<Map<String, Object>> getEveryBuildPersonNumBerS() {
        return lwgyBaseApartmentMapper.getEveryBuildPersonNumBerS();
    }

    @Override
    public List<LwgyBaseApartment> getBuildCampus() {
        QueryWrapper<LwgyBaseApartment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type", "campus");
        return lwgyBaseApartmentMapper.selectList(queryWrapper);
    }


    private List<LwgyBaseApartment> findchildList(String id) {
        QueryWrapper<LwgyBaseApartment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("pid", id);//根据pid查询子节点
        List<LwgyBaseApartment> lwgyBaseApartments = baseMapper.selectList(queryWrapper);
        lwgyBaseApartmentList.addAll(lwgyBaseApartments);//将查询到的子节点添加到集合中
        for (LwgyBaseApartment lwgyBaseApartment : lwgyBaseApartments) {//遍历子节点
            findchildList(lwgyBaseApartment.getId());//查找子节点中的子节点
        }
        return lwgyBaseApartmentList;
    }

    public static synchronized String getSubInnerCode(String parentCode, String localCode) {
        if (localCode != null && localCode != "") {
            return getNextInnerCode(localCode);

        } else {
            parentCode = parentCode + "0001";
        }
        return parentCode;
    }

    private static String getNextInnerCode(String localCode) {
        if (oConvertUtils.isNotEmpty(localCode)) {
            if (localCode.length() > 3) {
                String suffix = localCode.substring(0, localCode.length() - 4);//前缀
                String prefix = localCode.substring(localCode.length() - 4);//
                int i = Integer.parseInt(prefix) + 1;
                return suffix+String.format("%0" + 4 + "d", i);
            }else{
                int i = Integer.parseInt(localCode) + 1;
                return String.format("%0" + 3 + "d", i);
            }

        } else {
            return "0001";
        }
    }

    @Test
    public void test11() {
        String subInnerCode = getSubInnerCode("001", "");
        System.out.println("subInnerCode = " + subInnerCode);
    }

    public List<Map<String,String>> getFjInfoById(String id){
        return lwgyBaseApartmentMapper.getFjInfoById(id);
    }

    public Boolean updateXqJob(){
     try{
         QueryWrapper<LwgyBaseApartment> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("type","campus");
         List<LwgyBaseApartment> list = this.list(queryWrapper);//xqlist

         List<LwgyBaseApartment>  endLwgyBaseApartment =new ArrayList<>();
         if(oConvertUtils.isNotEmpty(list)) {
             for (int i = 1; i <= list.size(); i++) {
                 //将校区里面的code 赋值 i
                 LwgyBaseApartment endXqList = (LwgyBaseApartment) list.get(i-1);
                 endXqList.setCode(i + "");
                 endLwgyBaseApartment.add(endXqList);
             }
         }
         Boolean result1 =  this.updateBatchById(endLwgyBaseApartment);
         Boolean result2 = updateApartmentJob("campus","building");
         Boolean result3 = updateApartmentJob("building","unit");
         Boolean result4 = updateApartmentJob("unit","layer");
         Boolean result5 = updateApartmentJob("layer","room");
         Boolean result6 = updateCwhJob();
         if(result1 && result2 && result3 && result4  && result5 && result6){
             return true;
         }else{
             return false;
         }
     }catch (Exception e){
         return false;
     }
 }


    public Boolean updateCwhJob(){
        try{
            QueryWrapper<LwgyBaseApartment> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("type","room");
            List<LwgyBaseApartment> list = this.list(queryWrapper);//roomlist
            List<LwgyBaseBed> list2 = lwgyBaseBedService.list();
            List<LwgyBaseBed>  endLwgyBaseBed =new ArrayList<>();
            for (int i = 1; i <= list.size(); i++) {
                LwgyBaseApartment apartment1 =list.get(i-1);
                List<LwgyBaseBed> list3 = list2.stream().filter(item->item.getRoomId().equals(apartment1.getId())).collect(Collectors.toList())    ;
                for(int k=1;k<=list3.size();k++){
                    LwgyBaseBed apartment2 =list3.get(k-1);
                    apartment2.setBedCode(apartment1.getCode()+"-"+k);
                    endLwgyBaseBed.add(apartment2);
                    }
            }
            Boolean result1 =  lwgyBaseBedService.updateBatchById(endLwgyBaseBed);
            if(result1){
                return true;
            }else{
                return false;
            }
        }catch (Exception e){
            return false;
        }
    }

    public Boolean  updateApartmentJob(String type1,String type2){
        try{
            QueryWrapper<LwgyBaseApartment> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("type",type1);
            List<LwgyBaseApartment> list = this.list(queryWrapper);//xqlist
            QueryWrapper<LwgyBaseApartment> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.eq("type",type2);
            List<LwgyBaseApartment> list2 = this.list(queryWrapper2);//list
            List<LwgyBaseApartment>  endLwgyBaseApartment =new ArrayList<>();

            for (int i = 1; i <= list.size(); i++) {
                LwgyBaseApartment apartment1 =list.get(i-1);
                List<LwgyBaseApartment> list3 = list2.stream().filter(item->item.getPid().equals(apartment1.getId())).collect(Collectors.toList())    ;
                for(int k=1;k<=list3.size();k++){
                    LwgyBaseApartment apartment2 =list3.get(k-1);
                    apartment2.setCode(apartment1.getCode()+"-"+k);
                    endLwgyBaseApartment.add(apartment2);
                }

            }
            Boolean result1 =  this.updateBatchById(endLwgyBaseApartment);
            if(result1){
                return true;
            }else{
                return false;
            }
        }catch (Exception e){
            return false;
        }
    }


    public List<Map<String,String>> getRoomInfo(){
        return lwgyBaseApartmentMapper.getRoomInfo();
    }
}


